package cn.edu.scau.cmi.ema.service;

import java.util.List;
import java.util.Set;

import org.springframework.stereotype.Service;

import org.springframework.transaction.annotation.Transactional;


import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Projections;
import org.hibernate.Session;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Projections;
import org.hibernate.Session;
import cn.edu.scau.cmi.ema.dao.*;
import cn.edu.scau.cmi.ema.domain.*;
import cn.edu.scau.cmi.ema.util.CmiSqlUtil;
import cn.edu.scau.cmi.ema.domain.base.CmiPagination;
import cn.edu.scau.cmi.ema.service.base.CmiEmaService;

import java.io.IOException;
import java.util.Map;
import java.util.HashMap;
import java.util.Set;
import java.util.HashSet;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

import javax.persistence.Query;
import java.util.Iterator;
@Service("CrawlerdetectstatusService")
@Transactional

public class CrawlerdetectstatusServiceImpl extends CmiEmaService implements CrawlerdetectstatusService {
	public CrawlerdetectstatusServiceImpl() {
	}

	@Transactional
	public Crawlerdetectstatus saveCrawlerdetectstatus(Crawlerdetectstatus crawlerdetectstatus) {
		Set<Crawlerdetect> existingCrawlerdetectsForCrawlerdetectstatus = new HashSet<Crawlerdetect>();
		Set<Crawlerevent> existingCrawlereventsForCrawlerdetectstatus = new HashSet<Crawlerevent>();

		Set<Crawlerdetect> selectedCrawlerdetectsForCrawlerdetectstatus = crawlerdetectstatus
				.getCrawlerdetectsForCrawlerdetectstatus();
		Set<Crawlerevent> selectedCrawlereventsForCrawlerdetectstatus = crawlerdetectstatus
				.getCrawlereventsForCrawlerdetectstatus();

		if (crawlerdetectstatus.getId() == null) {

			Crawlerdetectstatus existingCrawlerdetectstatus = crawlerdetectstatusDAO
					.findCrawlerdetectstatusByPhysicalPrimaryKey(crawlerdetectstatus.getName());

			if (isEquals(crawlerdetectstatus, existingCrawlerdetectstatus)) {
				return existingCrawlerdetectstatus;
			}

			crawlerdetectstatus = crawlerdetectstatusDAO.store(crawlerdetectstatus);
			crawlerdetectstatusDAO.flush();

			for (Crawlerdetect relatedCrawlerdetect : selectedCrawlerdetectsForCrawlerdetectstatus) {
				relatedCrawlerdetect.setCrawlerdetectstatus(crawlerdetectstatus);
				crawlerdetectDAO.store(relatedCrawlerdetect);
			}
			for (Crawlerevent relatedCrawlerevent : selectedCrawlereventsForCrawlerdetectstatus) {
				relatedCrawlerevent.setCrawlerdetectstatus(crawlerdetectstatus);
				crawlereventDAO.store(relatedCrawlerevent);
			}
		} else {
			Crawlerdetectstatus existingCrawlerdetectstatus = crawlerdetectstatusDAO
					.findCrawlerdetectstatusByPrimaryKey(crawlerdetectstatus.getId());

			existingCrawlerdetectsForCrawlerdetectstatus = existingCrawlerdetectstatus
					.getCrawlerdetectsForCrawlerdetectstatus();
			existingCrawlereventsForCrawlerdetectstatus = existingCrawlerdetectstatus
					.getCrawlereventsForCrawlerdetectstatus();

			Set<Crawlerdetect> prepareDeleteCrawlerdetectsForCrawlerdetectstatus = new HashSet<Crawlerdetect>();
			Set<Crawlerdetect> prepareAddCrawlerdetectsForCrawlerdetectstatus = new HashSet<Crawlerdetect>();

			prepareDeleteCrawlerdetectsForCrawlerdetectstatus.addAll(selectedCrawlerdetectsForCrawlerdetectstatus);
			prepareDeleteCrawlerdetectsForCrawlerdetectstatus.addAll(existingCrawlerdetectsForCrawlerdetectstatus);

			prepareAddCrawlerdetectsForCrawlerdetectstatus.addAll(selectedCrawlerdetectsForCrawlerdetectstatus);
			prepareAddCrawlerdetectsForCrawlerdetectstatus.addAll(existingCrawlerdetectsForCrawlerdetectstatus);

			prepareDeleteCrawlerdetectsForCrawlerdetectstatus.removeAll(selectedCrawlerdetectsForCrawlerdetectstatus);
			prepareAddCrawlerdetectsForCrawlerdetectstatus.removeAll(existingCrawlerdetectsForCrawlerdetectstatus);

			for (Crawlerdetect relatedCrawlerdetect : prepareAddCrawlerdetectsForCrawlerdetectstatus) {
				relatedCrawlerdetect.setCrawlerdetectstatus(crawlerdetectstatus);
				crawlerdetectDAO.store(relatedCrawlerdetect);
			}

			for (Crawlerdetect relatedCrawlerdetect : prepareDeleteCrawlerdetectsForCrawlerdetectstatus) {
				relatedCrawlerdetect.setCrawlerdetectstatus(null);
				crawlerdetectDAO.store(relatedCrawlerdetect);
			}
			Set<Crawlerevent> prepareDeleteCrawlereventsForCrawlerdetectstatus = new HashSet<Crawlerevent>();
			Set<Crawlerevent> prepareAddCrawlereventsForCrawlerdetectstatus = new HashSet<Crawlerevent>();

			prepareDeleteCrawlereventsForCrawlerdetectstatus.addAll(selectedCrawlereventsForCrawlerdetectstatus);
			prepareDeleteCrawlereventsForCrawlerdetectstatus.addAll(existingCrawlereventsForCrawlerdetectstatus);

			prepareAddCrawlereventsForCrawlerdetectstatus.addAll(selectedCrawlereventsForCrawlerdetectstatus);
			prepareAddCrawlereventsForCrawlerdetectstatus.addAll(existingCrawlereventsForCrawlerdetectstatus);

			prepareDeleteCrawlereventsForCrawlerdetectstatus.removeAll(selectedCrawlereventsForCrawlerdetectstatus);
			prepareAddCrawlereventsForCrawlerdetectstatus.removeAll(existingCrawlereventsForCrawlerdetectstatus);

			for (Crawlerevent relatedCrawlerevent : prepareAddCrawlereventsForCrawlerdetectstatus) {
				relatedCrawlerevent.setCrawlerdetectstatus(crawlerdetectstatus);
				crawlereventDAO.store(relatedCrawlerevent);
			}

			for (Crawlerevent relatedCrawlerevent : prepareDeleteCrawlereventsForCrawlerdetectstatus) {
				relatedCrawlerevent.setCrawlerdetectstatus(null);
				crawlereventDAO.store(relatedCrawlerevent);
			}
			crawlerdetectstatus = crawlerdetectstatusDAO.store(crawlerdetectstatus);
			crawlerdetectstatusDAO.flush();
		}

		crawlerdetectDAO.flush();
		crawlereventDAO.flush();
		return crawlerdetectstatus;
	}

	public void deleteCrawlerdetectstatus(Crawlerdetectstatus crawlerdetectstatus) {
		crawlerdetectstatusDAO.remove(crawlerdetectstatus);
		crawlerdetectstatusDAO.flush();
	}

	@Transactional
	public void deleteCrawlerdetectstatuss(Set<Integer> deleteCrawlerdetectstatussId) {
		Query query = crawlerdetectstatusDAO.createNamedQuery("deleteCrawlerdetectstatussById", -1, -1);
		query.setParameter(1, deleteCrawlerdetectstatussId);
		query.executeUpdate();
	}

	@Transactional
	public Set<Crawlerdetectstatus> loadCrawlerdetectstatuss() {
		return crawlerdetectstatusDAO.findAllCrawlerdetectstatuss();

	}

	@Transactional
	public Set<Crawlerdetectstatus> loadReferenceCrawlerdetectstatuss(Set<Crawlerdetectstatus> crawlerdetectstatuss) {
		Iterator<Crawlerdetectstatus> crawlerdetectstatussIterator = crawlerdetectstatuss.iterator();
		Set<Crawlerdetectstatus> referencedCrawlerdetectstatuss = new HashSet<>();
		while (crawlerdetectstatussIterator.hasNext()) {
			Crawlerdetectstatus currentCrawlerdetectstatus = crawlerdetectstatussIterator.next();

			if (!currentCrawlerdetectstatus.getCrawlerdetectsForCrawlerdetectstatus().isEmpty()) {
				referencedCrawlerdetectstatuss.add(currentCrawlerdetectstatus);
				continue;
			}

			if (!currentCrawlerdetectstatus.getCrawlereventsForCrawlerdetectstatus().isEmpty()) {
				referencedCrawlerdetectstatuss.add(currentCrawlerdetectstatus);
				continue;
			}
		}
		return referencedCrawlerdetectstatuss;
	}

	public Set<Crawlerdetectstatus> loadCrawlerdetectstatussByIdSet(Set<Integer> crawlerdetectstatusIdSet) {

		Iterator<Integer> crawlerdetectstatusIdIterator = crawlerdetectstatusIdSet.iterator();
		Set<Crawlerdetectstatus> crawlerdetectstatusSet = new HashSet<>();
		while (crawlerdetectstatusIdIterator.hasNext()) {
			Integer id = crawlerdetectstatusIdIterator.next();
			Crawlerdetectstatus currentCrawlerdetectstatus = crawlerdetectstatusDAO.findCrawlerdetectstatusById(id);
			crawlerdetectstatusSet.add(currentCrawlerdetectstatus);
		}
		return crawlerdetectstatusSet;
	}

	@Transactional
	public List<Crawlerdetectstatus> findAllCrawlerdetectstatuss(Integer startResult, Integer maxRows) {
		return new java.util.ArrayList<Crawlerdetectstatus>(
				crawlerdetectstatusDAO.findAllCrawlerdetectstatuss(startResult, maxRows));
	}

	@Transactional
	public Crawlerdetectstatus findCrawlerdetectstatusByPrimaryKey(Integer id) {
		return crawlerdetectstatusDAO.findCrawlerdetectstatusByPrimaryKey(id);
	}

	@Transactional
	public Integer countCrawlerdetectstatuss() {
		return ((Long) crawlerdetectstatusDAO.createQuerySingleResult("select count(o) from Crawlerdetectstatus o")
				.getSingleResult()).intValue();
	}

	@Transactional
	public Integer countCrawlerdetectstatuss(CmiPagination page) {
		String sql = CmiSqlUtil.createCountHql(page, Crawlerdetectstatus.class);
		return ((Long) crawlerdetectstatusDAO.createQuerySingleResult(sql).getSingleResult()).intValue();
	}

	/**
	 * search for name with ajax
	 * 
	 */
	@Transactional
	public Integer countCrawlerdetectstatussByName(String queryName) {
		Query query = crawlerdetectstatusDAO.createNamedQuery("countCrawlerdetectstatussByName", -1, -1);
		query.setParameter(1, queryName);
		return new Long((long) query.getSingleResult()).intValue();
	}

	@Transactional
	public Integer countCrawlerdetectstatussByDetachedCriteria(CmiPagination page) {
		DetachedCriteria detachedCriteria = CmiSqlUtil.createDetachedCriteria(page, Crawlerdetectstatus.class);
		Session session = entityManager.unwrap(Session.class);
		detachedCriteria.setProjection(Projections.rowCount());
		return new Long((long) detachedCriteria.getExecutableCriteria(session).uniqueResult()).intValue();
	}

	public Map<String, ?> loadCrawlerdetectstatusObjectReferencedSet(Crawlerdetectstatus crawlerdetectstatus) {
		HashMap<String, Object> objectReferencedSetMap = new HashMap<>();

		Set<Integer> crawlerdetectsIds = new HashSet<Integer>();
		for (Crawlerdetect obj : crawlerdetectstatus.getCrawlerdetectsForCrawlerdetectstatus()) {

			crawlerdetectsIds.add(obj.getId());
		}
		objectReferencedSetMap.put("crawlerdetectsIds", crawlerdetectsIds);
		Set<Integer> crawlereventsIds = new HashSet<Integer>();
		for (Crawlerevent obj : crawlerdetectstatus.getCrawlereventsForCrawlerdetectstatus()) {

			crawlereventsIds.add(obj.getId());
		}
		objectReferencedSetMap.put("crawlereventsIds", crawlereventsIds);

		return objectReferencedSetMap;
	}

	public Map<String, ?> loadCrawlerdetectstatusClassReferencedSet(Crawlerdetectstatus crawlerdetectstatus) {
		HashMap<String, Object> classReferencedSetMap = new HashMap<>();
		classReferencedSetMap.put("crawlerdetects", crawlerdetectDAO.findAllCrawlerdetects());
		classReferencedSetMap.put("crawlerevents", crawlereventDAO.findAllCrawlerevents());

		return classReferencedSetMap;
	}

	public boolean isEquals(Crawlerdetectstatus crawlerdetectstatus, Object obj) {
		if (obj == crawlerdetectstatus)
			return true;
		if (!(obj instanceof Crawlerdetectstatus))
			return false;
		Crawlerdetectstatus comparedCrawlerdetectstatus = (Crawlerdetectstatus) obj;
		if (!CheckPropertyEqual(crawlerdetectstatus.getName(), comparedCrawlerdetectstatus.getName())) {
			return false;
		}
		return true;
	}

	public static <T> boolean CheckPropertyEqual(T originProperty, T comparedProperty) {
		// 基本类型经过参数传递后会自动装箱
		String[] className = originProperty.getClass().getName().split("\\.");
		if (className[0].equals("java") && className[1].equals("math")) {
			return ((Comparable) originProperty).compareTo(comparedProperty) == 0 ? true : false;
		} else {
			return originProperty.equals(comparedProperty);
		}
	}
}

